package com.justinbuser.net
{
	import com.justinbuser.singleton.Core;
	
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileStream;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	
	[Bindable] public class DynamicURLLoader extends URLLoader
	{
		public var uri:String;
		public var varz:Object;
		public var loadsAttempted:int=0;
		public var attemptsAllowed:int=1;
		public var localFile:Object;
		public var request:URLRequest;
		public const defaultContentType:String = "application/x-www-form-urlencoded";
		public const defaultMethod:String = URLRequestMethod.POST;
		private var complete:Function;
		private var progress:Function;
		private var io:Function;
		private var network:Function;
		private var security:Function;
		
		public function DynamicURLLoader(completeFunction:Function=null,progressFunction:Function=null,ioErrorFunction:Function=null,networkErrorFunction:Function=null,securityErrorFunction:Function=null)
		{
			super();
			complete = completeFunction;
			progress = progressFunction;
			io = ioErrorFunction;
			network = networkErrorFunction;
			security = securityErrorFunction;
			addEventListener(Event.COMPLETE,loadComplete);
			addEventListener(ProgressEvent.PROGRESS,progressEvent);
			addEventListener(IOErrorEvent.IO_ERROR,ioErrorEvent);
			addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorEvent);
			addEventListener(IOErrorEvent.NETWORK_ERROR,networkErrorEvent);
		}
		
		public function clearListeners():void{
			if(complete!=null) removeEventListener(Event.COMPLETE,complete);
			if(progress!=null) removeEventListener(ProgressEvent.PROGRESS,progress);
			if(io!=null) removeEventListener(IOErrorEvent.IO_ERROR,io);
			if(network!=null) removeEventListener(IOErrorEvent.NETWORK_ERROR,network);
			if(security!=null) removeEventListener(SecurityErrorEvent.SECURITY_ERROR,security);
			removeEventListener(Event.COMPLETE,loadComplete);
			removeEventListener(IOErrorEvent.IO_ERROR,Core.errorEvent);
			removeEventListener(SecurityErrorEvent.SECURITY_ERROR,Core.errorEvent);
			removeEventListener(IOErrorEvent.NETWORK_ERROR,Core.networkError);
		}
		
		public function open(url:String,url_varz:Object=null,attempts_allowed:int=1,method:String=defaultMethod,url_request:URLRequest=null,content_type:String=defaultContentType):void{
			loadsAttempted++;
			uri = url;
			attemptsAllowed=attempts_allowed;
			varz = url_varz ? url_varz : varz ? varz : new URLVariables();
			request = url_request ? url_request : request ? request : new URLRequest(uri);
			request.contentType = content_type;
			request.method = method;
			request.data=varz;
			super.load(request);
		}
		
		override public function load(req:URLRequest):void{
			request = req;
			super.load(request);
		}
		
		public function retry():void{
			open(uri,varz);	
		}
		
		public function set ioErrorListener(f:Function):void{ io=f; }
		public function set networkErrorListener(f:Function):void{ network=f; }
		public function set securityErrorListener(f:Function):void{ security=f; }
		public function set progressListener(f:Function):void{ progress=f; }
		public function set completeListener(f:Function):void{ complete=f; }
		
		private function loadComplete(e:Event):void
		{ 
			clearListeners();
			if(String(e.target.data).indexOf('error_id')>=0) log.error(e.target.data); 
			if(localFile){
				moveFile();
			}
			if(complete!==null) complete(e);
		}
		
		private function moveFile():void{
			try
			{
				var fileStream:FileStream = new FileStream();
				fileStream.open(File(localFile), 'write');
				fileStream.writeBytes(data);
				fileStream.close();
			}
			catch(error:IOError){
				trace(error.getStackTrace());
			}
		}
		
		private function ioErrorEvent(e:IOErrorEvent):void
		{ 
			trace(e.text);
			if(loadsAttempted < attemptsAllowed)
			{
				loadsAttempted++;
				trace('retrying load of:',uri,', attempt #:',loadsAttempted);
				super.load(request);
			}
			else
			{
				clearListeners();
				if(io!==null) io(e);
			}
			Core.errorEvent(e);
		}
		
		private function networkErrorEvent(e:IOErrorEvent):void
		{ 
			clearListeners();
			Core.networkError(e);
			if(network!==null) network(e);
		}
		
		private function securityErrorEvent(e:IOErrorEvent):void
		{ 
			clearListeners();
			Core.errorEvent(e);
			if(security!==null) security(e);
		}
		
		private function progressEvent(e:ProgressEvent):void
		{ 
			if(progress!==null) progress(e);
		}
		
	}
}